// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   LinePlotter.java

package com.java4less.rchart;

import com.java4less.rchart.gc.ChartGraphics;
import com.java4less.rchart.gc.ChartImage;
import com.java4less.rchart.gc.Polygon;
import java.util.Vector;

// Referenced classes of package com.java4less.rchart:
//			Plotter, LineDataSerie, MaxMinDataSerie, FillStyle, 
//			ChartLabel, DataSerie, Scale, LineStyle

public class LinePlotter extends Plotter
{

	public boolean hideCeros;
	public static final int TYPE_LINE = 0;
	public static final int TYPE_CUBIC_NATURAL = 1;
	public static final int TYPE_B_SPLINES = 2;
	public static final int TYPE_LEAST_SQUARES_LINE = 3;
	public static final int MM_NORMAL = 0;
	public static final int MM_OHLC = 1;
	public static final int MM_CANDLESTICK = 2;
	public boolean fixedLimits;
	public int MaxMinType;
	public int pointSize;
	protected int bottomCorners[][];

	public LinePlotter()
	{
		hideCeros = false;
		fixedLimits = false;
		MaxMinType = 0;
		pointSize = 6;
		bottomCorners = new int[2][2];
	}

	protected double[][] clipLines(double Points[][], double MaxY, double MinY)
	{
		int position = 0;
		int lastPointPosition = 0;
		double result[][] = new double[2][Points[0].length * 2];
		int resultCount = 0;
		if (Points[0].length == 0)
			return Points;
		if (Points[1][0] < MinY)
			lastPointPosition = 1;
		if (Points[1][0] > MaxY)
			lastPointPosition = 2;
		if (lastPointPosition == 0)
		{
			result[0][0] = Points[0][0];
			result[1][0] = Points[1][0];
			resultCount++;
		}
		for (int i = 1; i < Points[0].length; i++)
		{
			position = 0;
			if (Points[1][i] < MinY)
				position = 1;
			if (Points[1][i] > MaxY)
				position = 2;
			if (position == 0 && lastPointPosition == 0)
			{
				result[0][resultCount] = Points[0][i];
				result[1][resultCount] = Points[1][i];
				resultCount++;
			}
			if (position != lastPointPosition && (position == 0 || lastPointPosition == 0))
			{
				double limit = MinY;
				if (position == 2 || lastPointPosition == 2)
					limit = MaxY;
				double slope = (Points[0][i] - Points[0][i - 1]) / (Points[1][i] - Points[1][i - 1]);
				double newX = Points[0][i - 1] + slope * (limit - Points[1][i - 1]);
				double newX1 = Points[0][i];
				if (position == 0 && newX1 < newX)
				{
					result[0][resultCount] = newX1;
					result[1][resultCount] = Points[1][i];
					resultCount++;
				}
				result[0][resultCount] = newX;
				result[1][resultCount] = limit;
				resultCount++;
				if (position == 0 && newX1 >= newX)
				{
					result[0][resultCount] = newX1;
					result[1][resultCount] = Points[1][i];
					resultCount++;
				}
			}
			if (position != lastPointPosition && position != 0 && lastPointPosition != 0)
			{
				double slope = (Points[0][i] - Points[0][i - 1]) / (Points[1][i] - Points[1][i - 1]);
				double newX1 = Points[0][i - 1] + slope * (MaxY - Points[1][i - 1]);
				double newX2 = Points[0][i - 1] + slope * (MinY - Points[1][i - 1]);
				if (position == 2)
				{
					result[0][resultCount] = newX2;
					result[1][resultCount] = MinY;
					resultCount++;
					result[0][resultCount] = newX1;
					result[1][resultCount] = MaxY;
					resultCount++;
				} else
				{
					result[0][resultCount] = newX1;
					result[1][resultCount] = MaxY;
					resultCount++;
					result[0][resultCount] = newX2;
					result[1][resultCount] = MinY;
					resultCount++;
				}
			}
			lastPointPosition = position;
		}

		double finalP[][] = new double[2][resultCount];
		for (int i = 0; i < resultCount; i++)
		{
			finalP[0][i] = result[0][i];
			finalP[1][i] = result[1][i];
		}

		return finalP;
	}

	protected void plotSerie(ChartGraphics g, DataSerie s, int serieSec)
	{
		s.hotAreas.removeAllElements();
		LineDataSerie l;
		if (s instanceof LineDataSerie)
			l = (LineDataSerie)s;
		else
			return;
		int count = l.getSize();
		int scX = 0;
		int scY = 0;
		int scYMin = 0;
		int scYMax = 0;
		int previousX = -1;
		int previousY = -1;
		boolean isNull = false;
		Scale tmpScaleY = super.getActiveYScale(s);
		Scale tmpScaleX = super.getActiveXScale(s);
		if (l.fillStyle != null && count > 1)
		{
			double Points[][] = new double[2][count + 2];
			double XValue = 0.0D;
			for (int i = 0; i < count; i++)
			{
				XValue = ((Double)l.getElementX(i)).doubleValue();
				double YValue;
				if (l.getElementY(i) == null)
					YValue = 0.0D;
				else
					YValue = ((Double)l.getElementY(i)).doubleValue();
				if (i == 0)
				{
					Points[0][0] = XValue;
					Points[1][0] = tmpScaleY.min;
				}
				Points[0][i + 1] = XValue;
				Points[1][i + 1] = YValue;
			}

			Points[0][count + 1] = XValue;
			Points[1][count + 1] = tmpScaleY.min;
			if (fixedLimits)
				Points = clipLines(Points, tmpScaleY.max, tmpScaleY.min);
			int PointsSC[][] = new int[2][Points[0].length];
			for (int i = 0; i < Points[0].length; i++)
			{
				PointsSC[0][i] = tmpScaleX.getScreenCoord(Points[0][i]);
				PointsSC[1][i] = tmpScaleY.getScreenCoord(Points[1][i]);
			}

			bottomCorners[0][0] = PointsSC[0][0];
			bottomCorners[1][0] = PointsSC[1][0];
			bottomCorners[0][1] = PointsSC[0][PointsSC[0].length - 1];
			bottomCorners[1][1] = PointsSC[1][PointsSC[0].length - 1];
			if (l.lineType == 0)
				l.fillStyle.drawPolygon(g, PointsSC[0], PointsSC[1], PointsSC[0].length);
		}
		double linePoints[][] = new double[2][count];
		boolean nullPoints[] = new boolean[count];
		for (int iteration = 0; iteration < 2; iteration++)
		{
			for (int i = 0; i < count; i++)
			{
				double XValue = ((Double)l.getElementX(i)).doubleValue();
				isNull = false;
				double YValue = 0.0D;
				if (l.getElementY(i) == null)
					isNull = true;
				else
					YValue = ((Double)l.getElementY(i)).doubleValue();
				if (l.fillStyle != null)
					isNull = false;
				scX = tmpScaleX.getScreenCoord(XValue);
				scY = tmpScaleY.getScreenCoord(YValue);
				nullPoints[i] = isNull;
				if (l.style != null && iteration == 0)
				{
					linePoints[0][i] = XValue;
					linePoints[1][i] = YValue;
				}
				if (l.vstyle != null && iteration == 1)
					l.vstyle.draw(g, scX, tmpScaleY.getScreenCoord(tmpScaleY.min), scX, scY);
				if ((l instanceof MaxMinDataSerie) && iteration == 0 && !((MaxMinDataSerie)l).bubbleChart && !isNull)
				{
					MaxMinDataSerie m = (MaxMinDataSerie)l;
					double YMinValue = ((Double)m.minData.elementAt(i)).doubleValue();
					double YMaxValue = ((Double)m.maxData.elementAt(i)).doubleValue();
					scYMin = tmpScaleY.getScreenCoord(YMinValue);
					scYMax = tmpScaleY.getScreenCoord(YMaxValue);
					m.maxminStyle.draw(g, scX, scYMin, scX, scYMax);
					if (m.drawLineEnd)
						m.maxminStyle.draw(g, scX - 3, scYMin, scX + 3, scYMin);
					if (m.drawLineEnd)
						m.maxminStyle.draw(g, scX - 3, scYMax, scX + 3, scYMax);
					if (MaxMinType == 1)
					{
						double tmpY = ((Double)m.getElementY(i)).doubleValue();
						scY = tmpScaleY.getScreenCoord(tmpY);
						m.maxminStyle.draw(g, scX - m.openCloseWidth, scY, scX, scY);
						YValue = ((Double)m.closeData.elementAt(i)).doubleValue();
						scY = tmpScaleY.getScreenCoord(YValue);
						m.maxminStyle.draw(g, scX + m.openCloseWidth, scY, scX, scY);
					}
					if (MaxMinType == 2)
					{
						double tmpY = ((Double)m.getElementY(i)).doubleValue();
						int scYOpen = tmpScaleY.getScreenCoord(tmpY);
						tmpY = ((Double)m.closeData.elementAt(i)).doubleValue();
						int scYClose = tmpScaleY.getScreenCoord(tmpY);
						FillStyle fill = new FillStyle(m.positiveValueColor);
						if (scYClose > scYOpen)
						{
							fill = new FillStyle(m.negativeValueColor);
							int t = scYClose;
							scYClose = scYOpen;
							scYOpen = t;
						}
						fill.draw(g, scX - m.openCloseWidth / 2, scYClose, scX + m.openCloseWidth / 2, scYOpen);
						m.maxminStyle.drawRect(g, scX + m.openCloseWidth / 2, scYOpen, scX - m.openCloseWidth / 2, scYClose);
					}
				}
				if (l.drawPoint && iteration == 1 && isNull)
				{
					Polygon p = new Polygon();
					p.addPoint(0, 0);
					p.addPoint(0, 0);
					p.addPoint(0, 0);
					p.addPoint(0, 0);
					l.hotAreas.addElement(p);
				}
				if (l.drawPoint && iteration == 1 && !isNull && YValue <= tmpScaleY.max && YValue >= tmpScaleY.min)
				{
					g.setColor(l.pointColor);
					Polygon p = new Polygon();
					if (l.icon == null)
					{
						int halfPoint = pointSize / 2;
						g.fillRect(scX - halfPoint, scY - halfPoint, pointSize, pointSize);
						p.addPoint(scX - halfPoint, scY - halfPoint);
						p.addPoint(scX - halfPoint, scY + halfPoint);
						p.addPoint(scX + halfPoint, scY + halfPoint);
						p.addPoint(scX + halfPoint, scY - halfPoint);
					} else
					{
						int iX = scX - l.icon.getWidth() / 2;
						int iY = scY - l.icon.getHeight() / 2;
						g.drawImage(l.icon, iX, iY);
						p.addPoint(iX, iY);
						p.addPoint(iX, iY + l.icon.getHeight());
						p.addPoint(iX + l.icon.getWidth(), iY + l.icon.getHeight());
						p.addPoint(iX + l.icon.getWidth(), iY);
					}
					l.hotAreas.addElement(p);
				}
				if ((l instanceof MaxMinDataSerie) && ((MaxMinDataSerie)l).bubbleChart && !isNull)
				{
					g.setColor(l.pointColor);
					double rValue = 0.0D;
					if (((MaxMinDataSerie)l).maxData.size() > i)
						rValue = ((Double)((MaxMinDataSerie)l).maxData.elementAt(i)).doubleValue();
					int r = tmpScaleY.getScreenCoord(rValue + YValue);
					r -= scY;
					if (r < 0)
						r = -1 * r;
					if (r > 0)
						if (((MaxMinDataSerie)l).fillBubble)
							g.fillArc(scX - r, scY - r, r * 2, r * 2, 0, 360);
						else
							g.drawArc(scX - r, scY - r, r * 2, r * 2, 0, 360);
				}
				if (l.valueFont != null && iteration == 1 && !isNull && YValue <= tmpScaleY.max && YValue >= tmpScaleY.min)
				{
					g.setColor(l.valueColor);
					g.setFont(l.valueFont);
					String txt = l.doubleToString(new Double(YValue));
					if (hideCeros && txt.compareTo("0") == 0)
						txt = "";
					String txtValue = txt;
					if (s.labelTemplate.length() > 0)
						txt = s.labelTemplate;
					if (s.dataLabels != null && s.dataLabels.length > i)
						txt = s.dataLabels[i];
					ChartLabel label = new ChartLabel(txt, txtValue, false, false);
					label.initialize(g, super.chart);
					label.paint(g, scX + 4, scY - 4 - label.requiredHeight, -1, -1);
				}
				previousX = scX;
				previousY = scY;
			}

			if (iteration != 0 || l.style == null)
				continue;
			if (fixedLimits)
				linePoints = clipLines(linePoints, tmpScaleY.max, tmpScaleY.min);
			int linePointsSC[][] = new int[2][linePoints[0].length];
			for (int j = 0; j < linePoints[0].length; j++)
			{
				isNull = false;
				if (!fixedLimits && nullPoints[j])
					isNull = true;
				if (!isNull)
				{
					linePointsSC[0][j] = tmpScaleX.getScreenCoord(linePoints[0][j]);
					linePointsSC[1][j] = tmpScaleY.getScreenCoord(linePoints[1][j]);
				}
			}

			if (l.lineType != 0)
			{
				plotCurve(g, linePointsSC, l);
				continue;
			}
			for (int j = 1; j < linePoints[0].length; j++)
			{
				isNull = false;
				if (!fixedLimits && (nullPoints[j] || nullPoints[j - 1]))
					isNull = true;
				if (isNull)
					continue;
				boolean draw = true;
				if (fixedLimits && linePoints[1][j - 1] == tmpScaleY.max && linePoints[1][j] == tmpScaleY.max)
					draw = false;
				if (fixedLimits && linePoints[1][j - 1] == tmpScaleY.min && linePoints[1][j] == tmpScaleY.min)
					draw = false;
				if (draw)
					l.style.draw(g, linePointsSC[0][j - 1], linePointsSC[1][j - 1], linePointsSC[0][j], linePointsSC[1][j]);
			}

		}

	}

	protected void plotCurve(ChartGraphics chartgraphics, int ai[][], LineDataSerie linedataserie)
	{
	}
}
